package com.government.org.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.government.app.bo.KeywordSearchBO;
import com.government.app.bo.KeywordSearchDetailsBO;
import com.government.app.vo.KeywordSearchDetailsVO;
import com.government.app.vo.KeywordSearchVO;
import com.government.area.domain.ParkArea;
import com.government.area.mapper.ParkAreaMapper;
import com.government.article.domain.ArticlePolicy;
import com.government.article.mapper.ArticlePolicyMapper;
import com.government.common.core.domain.BaseTreeVo;
import com.government.common.core.domain.entity.SysDictData;
import com.government.common.core.domain.entity.SysUser;
import com.government.common.core.domain.model.LoginUser;
import com.government.common.utils.*;
import com.government.member.domain.UserHobby;
import com.government.member.mapper.UserHobbyMapper;
import com.government.org.bo.OrgInfoBO;
import com.government.org.vo.OrgInfoVO;
import com.government.org.vo.OrgTreeVO;
import com.government.system.service.ISysDictTypeService;
import com.government.tag.domain.Tag;
import com.government.tag.mapper.TagMapper;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.government.org.mapper.OrgInfoMapper;
import com.government.org.domain.OrgInfo;
import com.government.org.service.IOrgInfoService;

import static com.government.common.utils.PageUtils.startPage;
import static com.government.common.utils.SecurityUtils.getLoginUser;

/**
 * 主管单位Service业务层处理
 *
 * @author system
 * @date 2023-09-14
 */
@Service
public class OrgInfoServiceImpl implements IOrgInfoService {
    @Autowired
    private OrgInfoMapper orgInfoMapper;

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private ParkAreaMapper parkAreaMapper;

    @Autowired
    private ArticlePolicyMapper articlePolicyMapper;

    @Autowired
    private UserHobbyMapper userHobbyMapper;

    @Autowired
    private ISysDictTypeService dictTypeService;

    /**
     * 查询主管单位
     *
     * @param orgId 主管单位主键
     * @return 主管单位
     */
    @Override
    public OrgInfo selectOrgInfoByOrgId(Long orgId) {
        OrgInfo orgInfo = orgInfoMapper.selectById(orgId);
//        if (StrUtil.isNotBlank(orgInfo.getTag())) {
//            orgInfo.setTags(Arrays.asList(orgInfo.getTag().split(",")));
//        }
        if (StrUtil.isNotBlank(orgInfo.getArea())) {
            String[] parkAreaIdStr = orgInfo.getArea().split(",");
            orgInfo.setParkAreaIds(Arrays.asList(parkAreaIdStr));
        }
        return orgInfo;
    }

    /**
     * 查询主管单位列表
     *
     * @param orgInfo 主管单位
     * @return 主管单位
     */
    @Override
    public List<OrgInfoVO> selectOrgInfoList(OrgInfoBO orgInfo) {

        List<OrgInfoVO> orgInfoVOList = orgInfoMapper.selectOrgInfoList(orgInfo);
        for (OrgInfoVO item : orgInfoVOList) {
            List<String> areaList = Lists.newArrayList();
            if (StrUtil.isNotBlank(item.getParkName1())) {
                areaList.add(item.getParkName1());
            }
            if (StrUtil.isNotBlank(item.getParkName2())) {
                areaList.add(item.getParkName2());
            }
            if (StrUtil.isNotBlank(item.getParkName3())) {
                areaList.add(item.getParkName3());
            }
            if (StrUtil.isNotBlank(item.getParkName4())) {
                areaList.add(item.getParkName4());
            }
            if (StrUtil.isNotBlank(item.getParkName5())) {
                areaList.add(item.getParkName5());
            }
            if (StrUtil.isNotBlank(item.getParkName6())) {
                areaList.add(item.getParkName6());
            }
            item.setAreaName(String.join("-", areaList));
        }
        return orgInfoVOList;
    }

    /**
     * 查询主管单位列表
     *
     * @return 主管单位
     */
    @Override
    public List<OrgTreeVO> getAll() {
        List<OrgInfo> orgInfoList = orgInfoMapper.selectAll();
        if (CollectionUtils.isEmpty(orgInfoList)) {

            return null;
        }
        HashMap<Long, List<OrgTreeVO>> allNodeMap = new HashMap<>();

        for (OrgInfo item : orgInfoList) {
            Long parentId = Objects.isNull(item.getParentOrgId()) ? 0 : item.getParentOrgId();
            List<OrgTreeVO> nodeList = allNodeMap.get(parentId);
            if (CollectionUtils.isEmpty(nodeList)) {

                nodeList = Lists.newArrayList();
            }
            OrgTreeVO treeVO = new OrgTreeVO();
            treeVO.setId(String.valueOf(item.getOrgId()));
            treeVO.setLabel(item.getOrgName());
            treeVO.setValue(item.getOrgId());
            nodeList.add(treeVO);
            allNodeMap.put(parentId, nodeList);
        }
        List<OrgTreeVO> rootNode = allNodeMap.get(0L);
        List<OrgTreeVO> orgTreeVOList = TreeUtils.buildTree(rootNode, allNodeMap);
        return orgTreeVOList;
    }

    /**
     * 查询主管单位列表
     *
     * @return 主管单位
     */
    @Override
    public List<OrgInfo> getAllOrgList() {
        List<OrgInfo> orgInfoList = orgInfoMapper.selectAll();
        for (OrgInfo item : orgInfoList) {
            if (StrUtil.isNotBlank(item.getArea())) {
                String[] parkAreaIdStr = item.getArea().split(",");
                item.setParkAreaIds(Arrays.asList(parkAreaIdStr));
            }
        }
        return orgInfoList;
    }

    /**
     * 新增主管单位
     *
     * @param orgInfo 主管单位
     * @return 结果
     */
    @Override
    public int insertOrgInfo(OrgInfoBO orgInfo) {
        SysUser user = getLoginUser().getUser();
//        if (CollUtil.isNotEmpty(orgInfo.getTags())) {
//            orgInfo.setTag(String.join(",", orgInfo.getTags()));
//        }

//        if (Objects.isNull(orgInfo.getParentOrgId())) {
//            orgInfo.setParkAreaId(String.join(",", orgInfo.getTags()));
//        }

        List<ParkArea> parkAreaList = parkAreaMapper.selectList(Wrappers.<ParkArea>lambdaQuery());
        Map<Long, String> parkAreaMap = parkAreaList.stream().collect(Collectors.toMap(ParkArea::getId, ParkArea::getName));

        // 园区
        if (CollUtil.isNotEmpty(orgInfo.getParkAreaIds())) {
            if (orgInfo.getParkAreaIds().size() > 0) {
                Long park1 = Long.parseLong(orgInfo.getParkAreaIds().get(0));
                orgInfo.setPark1(park1);
                orgInfo.setLastPark(park1);
                orgInfo.setParkName1(parkAreaMap.get(park1));
                orgInfo.setLastParkName(orgInfo.getParkName1());
            }
            if (orgInfo.getParkAreaIds().size() > 1) {
                Long park2 = Long.parseLong(orgInfo.getParkAreaIds().get(1));
                orgInfo.setPark2(park2);
                orgInfo.setLastPark(park2);
                orgInfo.setParkName2(parkAreaMap.get(park2));
                orgInfo.setLastParkName(orgInfo.getParkName2());
            }
            if (orgInfo.getParkAreaIds().size() > 2) {
                Long park3 = Long.parseLong(orgInfo.getParkAreaIds().get(2));
                orgInfo.setPark3(park3);
                orgInfo.setLastPark(park3);
                orgInfo.setParkName3(parkAreaMap.get(park3));
                orgInfo.setLastParkName(orgInfo.getParkName3());
            }
            if (orgInfo.getParkAreaIds().size() > 3) {
                Long park4 = Long.parseLong(orgInfo.getParkAreaIds().get(3));
                orgInfo.setPark4(park4);
                orgInfo.setLastPark(park4);
                orgInfo.setParkName4(parkAreaMap.get(park4));
                orgInfo.setLastParkName(orgInfo.getParkName4());
            }
            if (orgInfo.getParkAreaIds().size() > 4) {
                Long park5 = Long.parseLong(orgInfo.getParkAreaIds().get(4));
                orgInfo.setPark5(park5);
                orgInfo.setLastPark(park5);
                orgInfo.setParkName5(parkAreaMap.get(park5));
                orgInfo.setLastParkName(orgInfo.getParkName5());
            }
            if (orgInfo.getParkAreaIds().size() > 5) {
                Long park6 = Long.parseLong(orgInfo.getParkAreaIds().get(5));
                orgInfo.setPark6(park6);
                orgInfo.setLastPark(park6);
                orgInfo.setParkName6(parkAreaMap.get(park6));
                orgInfo.setLastParkName(orgInfo.getParkName6());
            }
            orgInfo.setArea(String.join(",", orgInfo.getParkAreaIds()));
        }
        if ("1".equals(orgInfo.getIsPublish())) {
            orgInfo.setPublishTime(new Date());
            orgInfo.setAuditBy(String.valueOf(user.getUserId()));
            orgInfo.setAuditTime(new Date());
        }
        orgInfo.setCreateTime(DateUtils.getNowDate());
        orgInfo.setCreateBy(String.valueOf(user.getUserId()));
        orgInfo.setUpdateTime(DateUtils.getNowDate());
        orgInfo.setUpdateBy(String.valueOf(user.getUserId()));
        return orgInfoMapper.insert(orgInfo);
    }

    /**
     * 修改主管单位
     *
     * @param orgInfo 主管单位
     * @return 结果
     */
    @Override
    public int updateOrgInfo(OrgInfo orgInfo) {

        SysUser user = getLoginUser().getUser();
        if ("1".equals(orgInfo.getIsPublish())) {
            orgInfo.setPublishTime(new Date());
            orgInfo.setAuditBy(String.valueOf(user.getUserId()));
            orgInfo.setAuditTime(new Date());
        }
//        if (CollUtil.isNotEmpty(orgInfo.getTags())) {
//            orgInfo.setTag(String.join(",", orgInfo.getTags()));
//        }
        List<ParkArea> parkAreaList = parkAreaMapper.selectList(Wrappers.<ParkArea>lambdaQuery());
        Map<Long, String> parkAreaMap = parkAreaList.stream().collect(Collectors.toMap(ParkArea::getId, ParkArea::getName));

        // 园区
        if (CollUtil.isNotEmpty(orgInfo.getParkAreaIds())) {
            orgInfo.setPark1(null);
            orgInfo.setParkName1("");
            orgInfo.setPark2(null);
            orgInfo.setParkName2("");
            orgInfo.setPark3(null);
            orgInfo.setParkName3("");
            orgInfo.setPark4(null);
            orgInfo.setParkName4("");
            orgInfo.setPark5(null);
            orgInfo.setParkName5("");
            orgInfo.setPark6(null);
            orgInfo.setParkName6("");
            orgInfo.setLastPark(null);
            if (orgInfo.getParkAreaIds().size() > 0) {
                Long park1 = Long.parseLong(orgInfo.getParkAreaIds().get(0));
                orgInfo.setPark1(park1);
                orgInfo.setLastPark(park1);
                orgInfo.setParkName1(parkAreaMap.get(park1));
            }
            if (orgInfo.getParkAreaIds().size() > 1) {
                Long park2 = Long.parseLong(orgInfo.getParkAreaIds().get(1));
                orgInfo.setPark2(park2);
                orgInfo.setLastPark(park2);
                orgInfo.setParkName2(parkAreaMap.get(park2));
            }
            if (orgInfo.getParkAreaIds().size() > 2) {
                Long park3 = Long.parseLong(orgInfo.getParkAreaIds().get(2));
                orgInfo.setPark3(park3);
                orgInfo.setLastPark(park3);
                orgInfo.setParkName3(parkAreaMap.get(park3));
            }
            if (orgInfo.getParkAreaIds().size() > 3) {
                Long park4 = Long.parseLong(orgInfo.getParkAreaIds().get(3));
                orgInfo.setPark4(park4);
                orgInfo.setLastPark(park4);
                orgInfo.setParkName4(parkAreaMap.get(park4));
            }
            if (orgInfo.getParkAreaIds().size() > 4) {
                Long park5 = Long.parseLong(orgInfo.getParkAreaIds().get(4));
                orgInfo.setPark5(park5);
                orgInfo.setLastPark(park5);
                orgInfo.setParkName5(parkAreaMap.get(park5));
            }
            if (orgInfo.getParkAreaIds().size() > 5) {
                Long park6 = Long.parseLong(orgInfo.getParkAreaIds().get(5));
                orgInfo.setPark6(park6);
                orgInfo.setLastPark(park6);
                orgInfo.setParkName6(parkAreaMap.get(park6));
            }
            orgInfo.setArea(String.join(",", orgInfo.getParkAreaIds()));
        }

        orgInfo.setUpdateBy(String.valueOf(user.getUserId()));
        orgInfo.setUpdateTime(DateUtils.getNowDate());
        OrgInfo orgInfoUpd = BeanUtil.copyProperties(orgInfo, OrgInfo.class);
        if (Objects.isNull(orgInfoUpd.getParentOrgId())) {
            orgInfoUpd.setParentOrgId(0l);
        }

        return orgInfoMapper.updateById(orgInfoUpd);
    }

    /**
     * 批量删除主管单位
     *
     * @param orgIds 需要删除的主管单位主键
     * @return 结果
     */
    @Override
    public int deleteOrgInfoByOrgIds(Long[] orgIds) {
        return orgInfoMapper.deleteOrgInfoByOrgIds(orgIds);
    }

    /**
     * 删除主管单位信息
     *
     * @param orgId 主管单位主键
     * @return 结果
     */
    @Override
    public int deleteOrgInfoByOrgId(Long orgId) {
        OrgInfo orgInfo = orgInfoMapper.selectOrgInfoByOrgId(orgId);
        orgInfo.setIsDeleted("1");
        orgInfo.setUpdateTime(new Date());
        orgInfo.setUpdateBy(String.valueOf(getLoginUser().getUserId()));
        return orgInfoMapper.updateById(orgInfo);
    }

    /**
     * 搜索部门
     *
     * @return 文章资讯信息
     */
    @Override
    public List<KeywordSearchVO> selectOrgList(KeywordSearchBO bo) {

        // 获取当前的用户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser currentUser = null;
        if (StringUtils.isNotNull(loginUser) && !loginUser.isVisitor()) {
            currentUser = loginUser.getUser();

        }

        List<Tag> tagList = tagMapper.selectList(Wrappers.lambdaQuery());
        Map<String, Long> tagNamesMap = tagList.stream().collect(Collectors.toMap(Tag::getName, Tag::getId));
        List<String> tagIds = Lists.newArrayList();
        // 机构职能标签
        if (CollUtil.isNotEmpty(bo.getOrgTypes())) {
            for (String orgType : bo.getOrgTypes()) {
                Long tagId = tagNamesMap.get(orgType);
                if (Objects.nonNull(tagId)) {
                    tagIds.add(String.valueOf(tagId));
                }
            }
        }
        bo.setTagIds(tagIds);
        startPage();
        List<KeywordSearchVO> result = orgInfoMapper.selectOrgList(bo);
        List<Long> sourceIds = Lists.newArrayList();
        for (KeywordSearchVO item : result) {
            sourceIds.add(item.getId());
        }
        List<Long> likeFlagIds = Lists.newArrayList();
        List<Long> collectFlagIds = Lists.newArrayList();
        if (Objects.nonNull(currentUser) && CollUtil.isNotEmpty(result)) {
            UserHobby query = new UserHobby();
            query.setUserId(currentUser.getUserId());
            query.setSourceIds(sourceIds);
            query.setType("1");
            query.setSourceType("1");
            likeFlagIds = userHobbyMapper.getUserHobbyFlag(query);
            query.setType("2");
            collectFlagIds = userHobbyMapper.getUserHobbyFlag(query);
        }
        List<SysDictData> orgTypeList = dictTypeService.selectDictDataByType("org_type");
        Map<String, String> orgTypeMap = orgTypeList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        for (KeywordSearchVO item : result) {

            if (StrUtil.isNotBlank(item.getParentOrgName())) {
                if ("0".equals(item.getParentOrgName())) {
                    item.setParentOrgName("国家");
                }
            }
            if (Objects.nonNull(currentUser)) {

                if (likeFlagIds.contains(item.getId())) {
                    item.setIsLike("1");
                }
                if (collectFlagIds.contains(item.getId())) {
                    item.setIsCollect("1");
                }
            }
            item.setType(orgTypeMap.get(item.getType()));
        }
        return result;
    }

    /**
     * 搜索部门详情
     */
    @Override
    public KeywordSearchDetailsVO selectOrgDetails(KeywordSearchDetailsBO bo) {

        KeywordSearchDetailsVO keywordSearchDetailsVO = orgInfoMapper.selectOrgDetails(bo);
        int count = articlePolicyMapper.selectCount(Wrappers.<ArticlePolicy>lambdaQuery().eq(ArticlePolicy::getOrgId, bo.getId()));
        if (Objects.nonNull(keywordSearchDetailsVO)) {
            keywordSearchDetailsVO.setExistPolicy(count > 0 ? "1" : "0");
        }
        return keywordSearchDetailsVO;
    }

    /**
     * 根据部门id查询所属部门树
     *
     * @param orgId
     * @return
     */
    @Override
    public List<BaseTreeVo> getParentOrgTree(Long orgId) {

        OrgInfo orgInfo = orgInfoMapper.selectById(orgId);

        // 最终处理结果Map
        TreeMap<Long, OrgInfo> orgInfoResultMap = new TreeMap<>();
        // 查询每个政策的树结构(最多4层结构) 查找逻辑：上找3层，下找3层
        findOrgInfoParentRel(orgInfo, orgInfoResultMap);

        HashMap<Long, List<BaseTreeVo>> allNodeMap = new HashMap<>();
        List<BaseTreeVo> rootNode = getBaseTreeVos(orgInfoResultMap, allNodeMap);
        if (CollUtil.isEmpty(rootNode)) {
            return Lists.newArrayList();
        }
        return TreeUtils.buildTree(rootNode, allNodeMap);
    }

    private void findParentOrg(OrgInfo orgInfo, TreeMap<Long, OrgInfo> orgInfoResultMap, Map<Long, OrgInfo> allOrgInfoMap) {
        if (Objects.nonNull(orgInfo.getParentOrgId())) {
            OrgInfo parentOrgInfo = allOrgInfoMap.get(orgInfo.getParentOrgId());
            if (Objects.nonNull(parentOrgInfo)) {
                orgInfoResultMap.put(parentOrgInfo.getOrgId(), parentOrgInfo);
                findParentOrg(parentOrgInfo, orgInfoResultMap, allOrgInfoMap);
            }
        }
    }

    private void findChildrenOrg(OrgInfo orgInfo, TreeMap<Long, OrgInfo> orgInfoResultMap, Map<Long, List<OrgInfo>> parentOrgInfoMap) {
        List<OrgInfo> childrenList = parentOrgInfoMap.get(orgInfo.getOrgId());
        if (CollUtil.isNotEmpty(childrenList)) {
            for (OrgInfo children : childrenList) {
                orgInfoResultMap.put(children.getOrgId(), children);
                findChildrenOrg(children, orgInfoResultMap, parentOrgInfoMap);
            }
        }
    }

    private List<BaseTreeVo> getBaseTreeVos(TreeMap<Long, OrgInfo> orgInfoResultMap, HashMap<Long, List<BaseTreeVo>> allNodeMap) {
//        List<OrgInfo> sortOrgInfoPolicy = orgInfoResultMap.values().stream().sorted(Comparator.comparing(ArticlePolicy::getSort1).thenComparing(ArticlePolicy::getSort2).thenComparing(ArticlePolicy::getSort3)).collect(Collectors.toList());
        for (OrgInfo item : orgInfoResultMap.values()) {

            Long parentId = Objects.isNull(item.getParentOrgId()) ? 0 : item.getParentOrgId();
            List<BaseTreeVo> nodeList = allNodeMap.get(parentId);
            if (CollectionUtils.isEmpty(nodeList)) {

                nodeList = Lists.newArrayList();
            }
            BaseTreeVo policyTreeVO = new BaseTreeVo();
            policyTreeVO.setId(String.valueOf(item.getOrgId()));
            policyTreeVO.setValue(item.getOrgId());
            policyTreeVO.setLabel(item.getOrgName());
            nodeList.add(policyTreeVO);
            allNodeMap.put(parentId, nodeList);
        }
        List<BaseTreeVo> rootNode = allNodeMap.get(0L);
        return rootNode;
    }

    // 查询部门下的政策树
    public List<BaseTreeVo> findOrgPolicy(Long orgId) {

        OrgInfo orgInfo = orgInfoMapper.selectById(orgId);

        ArticlePolicy articlePolicyQuery = new ArticlePolicy();
        articlePolicyQuery.setOrgId(orgId);
        List<ArticlePolicy> allPolicyList = articlePolicyMapper.getAllPolicy(articlePolicyQuery);
        // 所有政策Map
        List<BaseTreeVo> result = Lists.newArrayList();
        BaseTreeVo policyTreeVO = new BaseTreeVo();
        policyTreeVO.setId(String.valueOf(orgInfo.getOrgId()));
        policyTreeVO.setValue(orgInfo.getOrgId());
        policyTreeVO.setLabel(orgInfo.getOrgName());

        List<BaseTreeVo> childrenResult = Lists.newArrayList();
        for (ArticlePolicy articlePolicy : allPolicyList) {
            BaseTreeVo childrenPolicyTreeVO = new BaseTreeVo();
            childrenPolicyTreeVO.setId(String.valueOf(articlePolicy.getArticleId()));
            childrenPolicyTreeVO.setValue(articlePolicy.getArticleId());
            childrenPolicyTreeVO.setLabel(articlePolicy.getName());
            childrenResult.add(childrenPolicyTreeVO);
        }
        policyTreeVO.setChildren(childrenResult);
        result.add(policyTreeVO);
        return result;
    }

    // 查询所属关系政策树
    private void findOrgInfoParentRel(OrgInfo orgInfo, TreeMap<Long, OrgInfo> orgInfoResultMap) {

        List<OrgInfo> allOrgList = orgInfoMapper.getAllOrgList();
        // 所有政策Map
        Map<Long, OrgInfo> allOrgInfoMap = allOrgList.stream().collect(Collectors.toMap(OrgInfo::getOrgId, x -> x));
        // 根据父级政策分组Map
        Map<Long, List<OrgInfo>> parentOrgInfoMap = allOrgList.stream().filter(item -> Objects.nonNull(item.getParentOrgId())).collect(Collectors.groupingBy(OrgInfo::getParentOrgId));

        orgInfoResultMap.put(orgInfo.getOrgId(), orgInfo);

        // 获取所有父级机构
        findParentOrg(orgInfo, orgInfoResultMap, allOrgInfoMap);

        // 获取所有子级机构
        findChildrenOrg(orgInfo, orgInfoResultMap, parentOrgInfoMap);

    }

    @Override
    public void browseNumAdd(Long articleId) {

        orgInfoMapper.browseAdd(articleId);
    }

}
